package mirfordevoservice.system.GameCenter;

/**
 * Created by Heart!
 *
 * @Author ZhangChaoJian
 * @Date 2018/3/26.8:55
 * Wants More Then Try Hard More!
 */

import mirfordevoservice.data.UrlPathLoader;
import mirfordevoservice.system.gamethreadpool.ThreadPoolManager;
import publicPackage.human.Role;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import static mirfordevoservice.system.contasnt.GameConstant.CacheCenter.HUMAN_ALL_DATA;
import static mirfordevoservice.system.contasnt.GameConstant.GameDataStream.*;
import static mirfordevoservice.system.contasnt.GameConstant.GameSafe.OPEN_SAFETY_SAVING;

/**
 * 游戏数据中心
 */
public class DataCenter {
    private static final DataCenter INSTANCE = new DataCenter();

    private DataCenter() {
        initAllDataForCenter();//初始化人物信息
        startSaveHumanDataThread();//保存数据的线程
    }

    public static DataCenter getInstance() {
        return INSTANCE;
    }

    /**
     * 通过字段返回需要的人物配置
     */
    public Integer getHumanConfigByKeyName(String kind, String id) {
        return HUMAN_ALL_DATA.get(kind).get(id);
    }

    /**
     * 通过账号获取用户role
     *
     * @param count
     * @return
     */
    public Role getRoleByCountName(String count) {
        return ALL_ROLES.get(COUNT_ROLES.get(count));
    }

    /**
     * 通过ID获取用户
     *
     * @param id
     * @return
     */
    public Role getRoleByID(long id) {
        return ALL_ROLES.get(id);
    }

    /**
     * 初始化所有的信息集合
     */
    private void initAllDataForCenter() {
        try {
            readFileToGetData();
            readFileToGetNameData();
            readFileToGetNameListData();
        } catch (Exception e) {
            System.err.println("读取人物数据时出错...");
        }
    }

    /**
     * 读取名字集合
     */
    private void readFileToGetNameListData() {
        File dataOfAllRoles = new File(UrlPathLoader.getInstance().getSrcPath("Data/NameList"));
        try {
            ObjectInputStream dataRoles = new ObjectInputStream(new FileInputStream(dataOfAllRoles));
            Object o;
            while ((o = dataRoles.readObject()) != null) {
                Set<String> readFileToGetData = (Set<String>) o;
                NAME_LIST.addAll(readFileToGetData);
            }
            dataRoles.close();
            System.err.print("已用名字集合加载完成数据加载完成...\t");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 读取角色名字对应信息
     */
    private void readFileToGetNameData() {
        File dataOfAllRoles = new File(UrlPathLoader.getInstance().getSrcPath("Data/CountAndName"));
        try {
            ObjectInputStream dataRoles = new ObjectInputStream(new FileInputStream(dataOfAllRoles));
            Object o;
            while ((o = dataRoles.readObject()) != null) {
                Map<String, Long> readFileToGetData = (Map<String, Long>) o;
                COUNT_ROLES.putAll(readFileToGetData);
            }
            dataRoles.close();
            System.err.print("角色-名字数据加载完成...\t");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }


    /**
     * 读取角色数据
     */
    private void readFileToGetData() {
        File dataOfAllRoles = new File(UrlPathLoader.getInstance().getSrcPath("Data/AllRoles"));
        try {
            ObjectInputStream dataRoles = new ObjectInputStream(new FileInputStream(dataOfAllRoles));
            Object o;
            while ((o = dataRoles.readObject()) != null) {
                Map<Long, Role> readFileToGetData = (Map<Long, Role>) o;
                ALL_ROLES.putAll(readFileToGetData);
            }
            dataRoles.close();
            System.err.print("角色-ID数据加载完成...\t");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    static int LAST_OF_SECONDS = (int) (System.currentTimeMillis() / 60000l);

    /**
     * 开启保存数据线程 一分钟一次
     */
    private void startSaveHumanDataThread() {
        System.err.println("开启人物数据存储线程运行中...");
        try {
            ThreadPoolManager.threadPoolManager.execute(new Thread(() -> {
                new Timer(10000, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        int nowOfSecond = (int) (System.currentTimeMillis() / 60000l);
                        if (nowOfSecond != LAST_OF_SECONDS) {
                            LAST_OF_SECONDS = nowOfSecond;
                            long before = System.currentTimeMillis();
                            savingRole_ID();
                            savingRole_Name();
                            savingNameSet();
                            long after = System.currentTimeMillis();
                            System.err.println("数据保存完成，用时:\t" + (after - before) + "ms");
                        }
                    }
                }).start();
            }));
        } catch (Exception e) {
            System.err.println("保存人物数据时出错...");
        }
    }

    /**
     * 手动调用持久化
     */
    public void savingData() {
        if (OPEN_SAFETY_SAVING) {
            long before = System.currentTimeMillis();
            savingRole_ID();
            savingRole_Name();
            savingNameSet();
            long after = System.currentTimeMillis();
            System.err.println("数据保存完成，用时:\t" + (after - before) + "ms");
        }
    }

    /**
     * 游戏关闭时执行操作
     */
    public void savingBeforeExit() {
        if (OPEN_SAFETY_SAVING) {
            long before = System.currentTimeMillis();
            savingRole_ID();
            savingRole_Name();
            savingNameSet();
            long after = System.currentTimeMillis();
            System.err.println("数据保存完成，用时:\t" + (after - before) + "ms");
        }
    }

    /**
     * 保存名字set
     */
    private void savingNameSet() {
        File dataOfAllRoles = new File(UrlPathLoader.getInstance().getSrcPath("Data/NameList"));
        if (!dataOfAllRoles.exists()) {
            try {
                dataOfAllRoles.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            ObjectOutputStream dataRoles = new ObjectOutputStream(new FileOutputStream(dataOfAllRoles));
            dataRoles.writeObject(NAME_LIST);
            dataRoles.writeObject(null);
            dataRoles.flush();
            dataRoles.close();
            System.err.print("名字数据保存完成...\t");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 保存角色-名字
     */
    private void savingRole_Name() {
        File dataOfAllRoles = new File(UrlPathLoader.getInstance().getSrcPath("Data/CountAndName"));
        if (!dataOfAllRoles.exists()) {
            try {
                dataOfAllRoles.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            ObjectOutputStream dataRoles = new ObjectOutputStream(new FileOutputStream(dataOfAllRoles));
            dataRoles.writeObject(COUNT_ROLES);
            dataRoles.writeObject(null);
            dataRoles.flush();
            dataRoles.close();
            System.err.print("角色-名字数据保存完成...\t");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 保存角色-ID数据
     */
    private void savingRole_ID() {
        File dataOfAllRoles = new File(UrlPathLoader.getInstance().getSrcPath("Data/AllRoles"));
        if (!dataOfAllRoles.exists()) {
            try {
                dataOfAllRoles.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            ObjectOutputStream dataRoles = new ObjectOutputStream(new FileOutputStream(dataOfAllRoles));
            dataRoles.writeObject(ALL_ROLES);
            dataRoles.writeObject(null);
            dataRoles.flush();
            dataRoles.close();
            System.err.print("角色-ID数据保存完成...\t");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 清除服务器玩家所有数据
     */
    public void clearAllData() {
        File dataOfAllRoles_AllRole = new File(UrlPathLoader.getInstance().getSrcPath("Data/AllRoles"));
        File dataOfAllRoles_CountName = new File(UrlPathLoader.getInstance().getSrcPath("Data/CountAndName"));
        File dataOfAllRoles_NameList = new File(UrlPathLoader.getInstance().getSrcPath("Data/NameList"));
        try {
            ObjectOutputStream dataRoles = new ObjectOutputStream(new FileOutputStream(dataOfAllRoles_AllRole));
            Map<Long, Role> roleMap = new ConcurrentHashMap<>();
            dataRoles.writeObject(roleMap);
            dataRoles.writeObject(null);
            dataRoles = new ObjectOutputStream(new FileOutputStream(dataOfAllRoles_CountName));
            Map<String, Long> idMap = new ConcurrentHashMap<>();
            dataRoles.writeObject(idMap);
            dataRoles.writeObject(null);
            dataRoles = new ObjectOutputStream(new FileOutputStream(dataOfAllRoles_NameList));
            Set<String> nameSet = new HashSet<>();
            dataRoles.writeObject(nameSet);
            dataRoles.writeObject(null);
            dataRoles.flush();
            dataRoles.close();
            System.err.println("角色档案清理完毕...\t");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

